home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / win / c / winet.com / EXC.C < prev    next >
Encoding:
C/C++ Source or Header  |  1988-02-04  |  4.3 KB  |  141 lines

  1. /*
  2.  * This is the file exc.c
  3.  * It contains the actual code required by the exception handler.
  4.  */
  5. #if !defined(LINT_ARGS)
  6. #define LINT_ARGS
  7. #endif
  8. #include <stdio.h>
  9. #include <signal.h>
  10. #include <process.h>
  11. #include "exc.h"
  12. /*#include "cortns.h"*/
  13.  
  14. #define TRUE 1
  15. #define FALSE 0
  16.  
  17. struct ExcContext *ExcList = NULL;
  18. #if 0
  19. static char *dummy; /* Because CHANGECO will save and restore 2 words for ExcList */
  20. struct CoRoutine _CoMain = {0, 0, 0, 0, 0};
  21. extern DWORD _CoCurrent;
  22. DWORD CoContC = (DWORD) &_CoMain;
  23. #endif
  24.  
  25. int exc_trace;
  26. int ExcNotInitialised = TRUE;
  27.  
  28. /* Declare exceptions that this package may signal */
  29. exception CONTROL_C = "***Break";
  30. exception OP_FAILED = "General failure";
  31. exception OUT_OF_MEMORY = "Out of memory";
  32.  
  33. static void exc_panic(char *, char *);
  34.  
  35. static int Xcont_C()
  36. {
  37. #if 0
  38.    if (_CoCurrent == CoContC)
  39.    {
  40.       signal(SIGINT, SIG_IGN);
  41.       if (exc_trace) fprintf(stderr, "Caught signal SIGINT\n");
  42.       (void) flushall();
  43.       setbuf(stdin, NULL); /* Otherwise things go funny */
  44.       signal(SIGINT, Xcont_C);
  45.       exc_raise(CONTROL_C);
  46.    }
  47.    else if (CoContC != (DWORD) NULL)
  48.    {
  49.       ((LPCO) CoContC) -> excpend = CONTROL_C;
  50.    }
  51. #endif
  52.    signal(SIGINT, Xcont_C);
  53.    return 0;
  54. };
  55.  
  56. /*
  57.  * Unfortunately, on PC-DOS this is the only signal that exists
  58.  */
  59.  
  60. static void exc_init()
  61. {
  62.    if (exc_trace) fprintf(stderr, "exc_init()\n");
  63.    ExcNotInitialised = FALSE;
  64.    signal(SIGINT, Xcont_C);
  65.    /* Any other signals set up here */
  66.    /* matherr ??? */
  67. }
  68.  
  69. /***************************************************************************
  70.  * This routine is called at every BEGIN statement. An exception could be  *
  71.  * substituted for the panic but since a jump out of a context is the most *
  72.  * usual cause, the saved contexts are garbage in this case.               *
  73.  ***************************************************************************/
  74. void exc_begin(ExcMostRecent)
  75. struct ExcContext *ExcMostRecent;
  76. {
  77.    if (ExcNotInitialised) exc_init();
  78.  
  79.    ExcMostRecent->link = ExcList;
  80.    ExcList = ExcMostRecent;
  81.    if (exc_trace)
  82.       fprintf(stderr, "BEGIN handling context %d\n", ExcList);
  83. };
  84.  
  85. /***************************************************************************
  86.  * This is called whenever a context is left normally.                     *
  87.  ***************************************************************************/
  88. void exc_1leave()
  89. {
  90.    if (exc_trace)
  91.       fprintf(stderr, "END exception context %d\n", ExcList);
  92.    ExcList = ExcList->link;
  93. }; /* End of exc_1leave */
  94.  
  95. /***************************************************************************
  96.  * This is called whenever a context is left because an exception was      *
  97.  * raised or signalled.                                                    *
  98.  ***************************************************************************/
  99. void exc_2leave()
  100. {
  101.    if (exc_trace)
  102.       fprintf(stderr, "EXCEPTION leave exception context %d\n", ExcList);
  103.    ExcList = ExcList->link;
  104. }; /* End of exc_2leave */
  105.  
  106. /***************************************************************************
  107.  * Raise an exception to be handled in current exception context.          *
  108.  ***************************************************************************/
  109. void exc_raise(code)
  110. exception code;
  111. {
  112.    if (exc_trace)
  113.       fprintf(stderr, "exc_raise(%s)\n", code);
  114.    if (ExcList == NULL) 
  115.       exc_panic("Raise %s: no context\n", (char *) code);
  116.    longjmp(ExcList->env, (int) code);
  117. }; /* End of exc_raise */
  118.  
  119. /***************************************************************************
  120.  * Raise an exception to be handled in outer exception context.            *
  121.  ***************************************************************************/
  122. void exc_signal(code)
  123. exception code;
  124. {
  125.    if (exc_trace)
  126.       fprintf(stderr, "exc_signal(%s)\nDISCARD context %d\n",
  127.                         code, ExcList);
  128.    if (ExcList == NULL || (ExcList = ExcList->link) == NULL)
  129.       exc_panic("Signal %s: no context\n", (char *) code);
  130.    longjmp(ExcList->env, (int) code);
  131. }; /* End of exc_raise */
  132.  
  133. static void exc_panic(s, p1)
  134. char *s, *p1;
  135. {
  136.    fprintf(stderr, "\nException panic - ");
  137.    fprintf(stderr, s, p1);
  138.    exit(99);   /* I want to do a core dump here! */
  139. }
  140.  
  141.